package com.xuhe.server.service.impl;

import com.alibaba.fastjson.JSON;
import com.xuhe.server.domain.db1.dao.gp.GpMapper;
import com.xuhe.server.domain.db1.dao.gp.HistoryMapper;
import com.xuhe.server.domain.db1.dataobject.gp.Gp;
import com.xuhe.server.domain.db1.dataobject.gp.History;
import com.xuhe.server.service.GpService;
import com.yszn.base.utils.DateUtil;
import io.netty.handler.codec.Headers;
import io.swagger.models.auth.In;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.Header;
import org.json.JSONArray;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.atomic.AtomicInteger;

@Service
@Slf4j
public class GpServiceImpl implements GpService {

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private GpMapper gpMapper;

    @Autowired
    private HistoryMapper historyMapper;

    @Autowired
    private ThreadPoolTaskExecutor taskExecutor;

    private static Integer threadMax = 100;

    @Override
    public void downloadNewGp() {
        try {
            String response = restTemplate.getForObject("https://ig507.com/data/base/gplist", String.class);

            log.info("开始下载最新股票...");
            JSONArray result = new JSONArray(response);
            if (result.length() > 0) {
                for (int i = 0; i < result.length(); i ++){
                    JSONObject object = result.getJSONObject(i);
                    log.info("{}", object);
                    if (object != null) {
                        Gp gp = new Gp();
                        gp.setDm(object.getString("dm"));
                        gp.setMc(object.getString("mc"));
                        gp.setJys(object.getString("jys"));
                        gpMapper.insert(gp);
                    }
                }
            }
            log.info("最新股票下载完成，共计：{}", result.length());
        }catch (Exception e){
            log.error("{}", e.getMessage());
        }
    }

    @Override
    public void downloadHisData(String code, String start, String end) {
        try {
            String url = "http://q.stock.sohu.com/hisHq?code=cn_" + code + "&start=" + start + "&end=" + end + "&&period=d&rt=json";
//            log.info("开始下载【{}】历史数据， start：{}， end：{}", code, start, end);
            String response = restTemplate.getForObject(url,  String.class);
            JSONArray result = new JSONArray(response);
            if (result.length() > 0) {
                for (int i = 0; i < result.length(); i ++){
                    JSONObject object = result.getJSONObject(i);
                    if (object != null) {
                        JSONArray hq = object.getJSONArray("hq");
                        if (hq != null) {
                            for (int j = 0; j < hq.length(); j ++){
                                JSONArray his = hq.getJSONArray(j);
                                History history = new History();
                                history.setCode(code);
                                history.setDate(his.getString(0));
                                history.setOpen(his.getString(1));
                                history.setClose(his.getString(2));
                                history.setCloseOpen(his.getString(3));
                                history.setRatio(his.getString(4));
                                history.setHigh(his.getString(6));
                                history.setMin(his.getString(5));
                                history.setTurnover(his.getString(7));
                                history.setVolume(his.getString(8));
                                history.setChangeHands(his.getString(9));
                                historyMapper.insert(history);
                            }
//                            log.info("【{}】历史数据下载完成，共计：{}", code, hq.length());
                        }
                    }
                }
            }
        }catch (Exception e){
            log.error("{}", e.getMessage());
        }
    }

    @SneakyThrows
    @Override
    public void downloadAllHisData(String start, String end) {
        List<String> codeList = gpMapper.findAllCode();
        log.info("区间：{} - {} 的历史数据开始下载......", start, end);
        AtomicInteger index = new AtomicInteger(0);
        int range = 1 + (codeList.size() / threadMax);

        historyMapper.deleteByCodeAndDate(null, start, end);

        start = start.replace("-", "");
        end = end.replace("-", "");

        List<Future<String>> threadList = new ArrayList<>();
        for (int rangI = 0; rangI < threadMax; rangI ++){
            int finalI = rangI;
            String finalStart = start;
            String finalEnd = end;
            Future<String> future = taskExecutor.submit(() -> {
                int st = finalI * range;
                int max = range * (finalI + 1);
                if (max > codeList.size()) max = codeList.size();
                for (int j = st; j < max; j ++){
                    this.downloadHisData(codeList.get(j), finalStart, finalEnd);
                    index.set(index.get() + 1);
                    log.info("已下载：{}个，进度：{}%", index.get(), (double)(index.get() * 1000/codeList.size())/10);
                }
                return "线程" + finalI + "执行结束";
            });
            threadList.add(future);
        }
        for (Future<String> future : threadList) {
            try {
                log.info("{}", future.get());
            } catch (InterruptedException | ExecutionException e) {
                throw new RuntimeException(e);
            }
        }
    }

    @Override
    public void downloadTodayData(String start, String end) {
        log.info("开始更新当日数据......");
        List<String> codeList = gpMapper.findAllSJYCode();

        AtomicInteger index = new AtomicInteger(0);
//        threadMax = 30;
        int range = 1 + (codeList.size() / threadMax);
        historyMapper.deleteByCodeAndDate(null, start, end);

        List<Future<String>> threadList = new ArrayList<>();
        for (int rangI = 0; rangI < threadMax; rangI ++){
            int finalI = rangI;
            Future<String> future = taskExecutor.submit(() -> {
                int st = finalI * range;
                int max = range * (finalI + 1);
                if (max > codeList.size()) max = codeList.size();
                for (int j = st; j < max; j ++){
                    this.downloadTodayData(codeList.get(j));
                    index.set(index.get() + 1);
                    log.info("已更新：{}个，进度：{}%", index.get(), (double)(index.get() * 1000/codeList.size())/10);
                }
                return "线程" + finalI + "执行结束";
            });
            threadList.add(future);
        }
        for (Future<String> future : threadList) {
            try {
                log.info("{}", future.get());
            } catch (InterruptedException | ExecutionException e) {
                throw new RuntimeException(e);
            }
        }
    }

    @Override
    public void downloadTodayData(String code) {
        try {
            HttpHeaders headers = new HttpHeaders();
            headers.add("referer", "http://finance.sina.com.cn");
            String url = "http://hq.sinajs.cn/list=" + code;
            HttpEntity<String> response = restTemplate
                    .exchange(url, HttpMethod.GET, new HttpEntity<>(null, headers),
                            String.class);

            if (response.getBody().startsWith("var hq_str_")){
                String[] list = response.getBody().split(",");
                int index = 0;
                if (list.length != 34 && list.length != 33){
                    log.error("{} {}", list.length, response.getBody());
                    return;
                }

                String date = list[30];
                History history = new History();
                history.setCode(code.substring(2));
                history.setDate(list[30]);
                history.setOpen(list[1]);
                history.setClose(list[3]);
                BigDecimal closeOpen = BigDecimal.valueOf(Double.parseDouble(list[3]) - Double.parseDouble(list[2])).setScale(2, RoundingMode.HALF_UP);
                history.setCloseOpen(String.valueOf(closeOpen));
                BigDecimal ratio = BigDecimal.valueOf(100 * closeOpen.doubleValue() / Double.parseDouble(list[2])).setScale(2, RoundingMode.HALF_UP);
                history.setRatio(ratio + "%");
                history.setHigh(list[4]);
                history.setMin(list[5]);
                history.setTurnover(String.valueOf(Integer.parseInt(list[8])/ 100));
                BigDecimal volume = BigDecimal.valueOf(Double.parseDouble(list[9])/ 10000).setScale(2, RoundingMode.HALF_UP);
                history.setVolume(String.valueOf(volume));
                history.setChangeHands(null);

                historyMapper.insert(history);
//                log.info("已下载：{}", history);
            }
        }catch (Exception e){
            log.error("{}", e.getMessage());
        }
    }
}
